home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / fs / fsCommand.c < prev    next >
C/C++ Source or Header  |  1991-05-30  |  13KB  |  499 lines

  1. /* 
  2.  * fsCommand.c --
  3.  *
  4.  *    The guts of the Fs_Command system call.  This is used to
  5.  *    set/get various filesystem parameters.
  6.  *
  7.  *
  8.  * Copyright 1985 Regents of the University of California
  9.  * Permission to use, copy, modify, and distribute this
  10.  * software and its documentation for any purpose and without
  11.  * fee is hereby granted, provided that the above copyright
  12.  * notice appear in all copies.  The University of California
  13.  * makes no representations about the suitability of this
  14.  * software for any purpose.  It is provided "as is" without
  15.  * express or implied warranty.
  16.  */
  17.  
  18. #ifndef lint
  19. static char rcsid[] = "$Header: /sprite/src/kernel/fs/RCS/fsCommand.c,v 9.6 91/05/30 13:20:19 shirriff Exp $ SPRITE (Berkeley)";
  20. #endif not lint
  21.  
  22.  
  23. #include <sprite.h>
  24. #include <fs.h>
  25. #include <fsutil.h>
  26. #include <fsNameOps.h>
  27. #include <fsprefix.h>
  28. #include <fsutilTrace.h>
  29. #include <fslcl.h>
  30. #include <fscache.h>
  31. #include <fspdev.h>
  32. #include <fsStat.h>
  33. #include <fsdm.h>
  34. #include <timer.h>
  35. #include <user/fsCmd.h>
  36. #include <rpc.h>
  37. #include <sched.h>
  38. #include <fsrmt.h>
  39. #include <vm.h>
  40. #include <stdlib.h>
  41. #include <stdio.h>
  42. #include <lfs.h>
  43.  
  44. #define SWAP_TO_BUFFER(int1, buffer) \
  45.     if ((int *)buffer != (int *)NIL && (int *)buffer != (int *)0) {    \
  46.     register int tmp;                        \
  47.     tmp = int1 ; int1 = *(int *)buffer ; *(int *)buffer = tmp;    \
  48.     }
  49.  
  50. /*
  51.  *----------------------------------------------------------------------
  52.  *
  53.  * Fs_Command --
  54.  *
  55.  *    Hook into the fs module.  System parameters can be adjusted,
  56.  *    the prefix table modified, and filesystem stats can be returned.
  57.  *
  58.  * Results:
  59.  *    0 or an error code from any of the operations.
  60.  *
  61.  * Side effects:
  62.  *    See description by each command.
  63.  *
  64.  *----------------------------------------------------------------------
  65.  */
  66. ReturnStatus
  67. Fs_Command(command, bufSize, buffer)
  68.     int command;
  69.     int bufSize;
  70.     Address buffer;
  71. {
  72.     ReturnStatus     status = SUCCESS;
  73.     extern    int    fscache_MaxBlockCleaners;
  74.     extern    int    fscache_NumReadAheadBlocks;
  75.     extern    Boolean    fsconsist_ClientCachingEnabled;
  76.  
  77.     switch(command) {
  78.     case FS_PREFIX_LOAD: {
  79.         /*
  80.          * Load the prefix and serverID into the prefix table.
  81.          * serverID is usually FS_NO_SERVER, although a known serverID
  82.          * can be loaded into the table.
  83.          */
  84.         Fs_PrefixLoadInfo *argPtr = (Fs_PrefixLoadInfo *) buffer;
  85.         if (argPtr->prefix[0] != '/' ||(argPtr->serverID < 0 || 
  86.         argPtr->serverID >= NET_NUM_SPRITE_HOSTS)) {
  87.         status = FS_INVALID_ARG;
  88.         } else {
  89.         int prefixFlags = FSPREFIX_IMPORTED;
  90.  
  91.         if (argPtr->serverID != RPC_BROADCAST_SERVER_ID) {
  92.             prefixFlags |= FSPREFIX_REMOTE | FSPREFIX_FORCED;
  93.         }
  94.         Fsprefix_Load(argPtr->prefix, argPtr->serverID, prefixFlags);
  95.         status = SUCCESS;
  96.         }
  97.         break;
  98.     }
  99.     case FS_PREFIX_EXPORT: {
  100.         /*
  101.          * Export a local directory under a prefix.
  102.          */
  103.         Fs_TwoPaths *argPtr = (Fs_TwoPaths *)buffer;
  104.         char *localPath, *prefix;
  105.         Fs_Stream *streamPtr;
  106.  
  107.         localPath = (char *)malloc(argPtr->pathLen1);
  108.         prefix = (char *)malloc(argPtr->pathLen2);
  109.         status = Vm_CopyIn(argPtr->pathLen1, argPtr->path1, localPath);
  110.         if (status == SUCCESS) {
  111.         status = Vm_CopyIn(argPtr->pathLen2, argPtr->path2, prefix);
  112.         if (status == SUCCESS) {
  113.             status = Fs_Open(localPath, FS_READ|FS_FOLLOW,
  114.                         FS_DIRECTORY, 0, &streamPtr);
  115.             if (status == SUCCESS) {
  116.             if (streamPtr->ioHandlePtr->fileID.type !=
  117.                 FSIO_LCL_FILE_STREAM) {
  118.                 printf(
  119.             "Tried to export non-local file \"%s\" as prefix \"%s\"\n",
  120.                 localPath, prefix);
  121.                 (void)Fs_Close(streamPtr);
  122.                 status = FS_NO_ACCESS;
  123.             } else {
  124.                 (void)Fsprefix_Install(prefix,streamPtr->ioHandlePtr,
  125.                             FS_LOCAL_DOMAIN,
  126.             FSPREFIX_EXPORTED|FSPREFIX_IMPORTED|FSPREFIX_OVERRIDE);
  127.             }
  128.             }
  129.         }
  130.         }
  131.         free(prefix);
  132.         free(localPath);
  133.         break;
  134.     }
  135.     case FS_PREFIX_CLEAR: {
  136.         /*
  137.          * Clear the handle information about a prefix.
  138.          */
  139.         status = Fsprefix_Clear(buffer, FALSE, TRUE);
  140.         break;
  141.     }
  142.     case FS_PREFIX_DELETE: {
  143.         /*
  144.          * Remote a prefix table entry all-together.
  145.          */
  146.         status = Fsprefix_Clear(buffer, TRUE, TRUE);
  147.         break;
  148.     }
  149.     case FS_PREFIX_CONTROL: {
  150.         /*
  151.          * Modify the export list associated with a prefix.
  152.          */
  153.         register Fs_PrefixControl *controlPtr;
  154.         controlPtr = (Fs_PrefixControl *)buffer;
  155.         if (bufSize < sizeof(Fs_PrefixControl)) {
  156.         status = GEN_INVALID_ARG;
  157.         } else {
  158.         Fsprefix_Export(controlPtr->prefix, controlPtr->clientID,
  159.                 controlPtr->delete);
  160.         status = SUCCESS;
  161.         }
  162.         break;
  163.     }
  164.     case FS_RAISE_MIN_CACHE_SIZE: {
  165.         /*
  166.          * Make the minimum size of the file system block cache larger.
  167.          */
  168.         if (buffer != (Address)NIL && buffer != (Address)0) {
  169.         Fscache_SetMinSize(*(int *) buffer);
  170.         }
  171.         break;
  172.     }
  173.     case FS_LOWER_MAX_CACHE_SIZE: {
  174.         /*
  175.          * Make the minimum size of the file system block cache larger.
  176.          */
  177.         if (buffer != (Address)NIL && buffer != (Address)0) {
  178.         Fscache_SetMaxSize(*(int *) buffer);
  179.         }
  180.         break;
  181.     }
  182.     case FS_DISABLE_FLUSH: {
  183.         /*
  184.          * Turn on or off automatic flushing of the cache.
  185.          */
  186.         SWAP_TO_BUFFER(fsutil_ShouldSyncDisks, buffer);
  187.         break;
  188.     }
  189.     /*
  190.      * The following cases are used to set flags and to
  191.      * return their old values.
  192.      */
  193.     case FS_SET_TRACING: {
  194.         /*
  195.          * Set the file system tracing flag.
  196.          */
  197.         SWAP_TO_BUFFER(fsutil_Tracing, buffer);
  198.         break;
  199.     }
  200.     case FS_SET_CACHE_DEBUG: {
  201.         /*
  202.          * Set the cache debug flag.
  203.          */
  204.         extern int fsconsist_Debug;
  205.         SWAP_TO_BUFFER(fsconsist_Debug, buffer);
  206.         break;
  207.     }
  208.     case FS_SET_MIG_DEBUG: {
  209.         /*
  210.          * Set the migration debug flag.
  211.          */
  212.         extern int fsio_MigDebug;
  213.         SWAP_TO_BUFFER(fsio_MigDebug, buffer);
  214.         break;
  215.     }
  216.     case FS_SET_PDEV_DEBUG: {
  217.         /*
  218.          * Set the pseudo-device debug flag.
  219.          */
  220.         extern Boolean  fspdev_Debug;
  221.         SWAP_TO_BUFFER(fspdev_Debug, buffer);
  222.         break;
  223.     }
  224.     case FS_SET_RPC_DEBUG: {
  225.         /*
  226.          * Set the rpc debug flag.
  227.          */
  228.         SWAP_TO_BUFFER(fsrmt_RpcDebug, buffer);
  229.         break;
  230.     }
  231.     case FS_SET_RPC_TRACING: {
  232.         /*
  233.          * Set the rpc tracing flag.
  234.          */
  235.         SWAP_TO_BUFFER(rpc_Tracing, buffer);
  236.         break;
  237.     }
  238.     case FS_SET_RPC_NO_TIMEOUTS: {
  239.         /*
  240.          * Set the rpc "no timeouts" flag, useful when debugging.
  241.          */
  242.         SWAP_TO_BUFFER(rpc_NoTimeouts, buffer);
  243.         break;
  244.     }
  245.     case FS_SET_NAME_CACHING: {
  246.         /*
  247.          * Set the rpc tracing flag.
  248.          */
  249.         extern int fslclNameCaching;
  250.         SWAP_TO_BUFFER(fslclNameCaching, buffer);
  251.         break;
  252.     }
  253.     case FS_SET_CLIENT_CACHING: {
  254.         /*
  255.          * Set the rpc tracing flag.
  256.          */
  257.         SWAP_TO_BUFFER(fsconsist_ClientCachingEnabled, buffer);
  258.         break;
  259.     }
  260.     case FS_SET_RPC_CLIENT_HIST: {
  261.         extern int rpcCallTiming;
  262.         SWAP_TO_BUFFER(rpcCallTiming, buffer);
  263.         break;
  264.     }
  265.     case FS_SET_RPC_SERVER_HIST: {
  266.         extern int rpcServiceTiming;
  267.         SWAP_TO_BUFFER(rpcServiceTiming, buffer);
  268.         break;
  269.     }
  270.     case FS_SET_NO_STICKY_SEGS: {
  271.         extern Boolean vm_NoStickySegments;
  272.         SWAP_TO_BUFFER(vm_NoStickySegments, buffer);
  273.         break;
  274.     }
  275.     case FS_TEST_CS: {
  276.         register    int    i;
  277.         Timer_Ticks    startTicks, endTicks, diffTicks;
  278.         Time    time;
  279.         int        us;
  280.  
  281.         Timer_GetCurrentTicks(&startTicks);
  282.         for (i = *(int *) buffer; i > 0; i--) {
  283.         Sched_ContextSwitch(PROC_READY);
  284.         }
  285.         Timer_GetCurrentTicks(&endTicks);
  286.         Timer_SubtractTicks(endTicks, startTicks, &diffTicks);
  287.         Timer_TicksToTime(diffTicks, &time);
  288.         us = (time.seconds * 1000000) + time.microseconds;
  289.         printf("microseconds = %d per CS = %d\n", us,
  290.                us / *(int *)buffer);
  291.         break;
  292.     }
  293.     case FS_EMPTY_CACHE: {
  294.         int *numLockedBlocksPtr = (int *)buffer;
  295.  
  296.         Fscache_Empty(numLockedBlocksPtr);
  297.         break;
  298.     }
  299.     case FS_ZERO_STATS: {
  300.         /*
  301.          * Zero out the counters in the fs_Stats struct.  Unfortunately,
  302.          * some values in the structure can't be zeroed out, so this
  303.          * must be changed to zero out only some portions.
  304.          */
  305.         bzero((Address) &fs_Stats, sizeof(Fs_Stats));
  306.         status = SUCCESS;
  307.         break;
  308.     }
  309.     case FS_RETURN_STATS: {
  310.         if (bufSize > 0) {
  311.         if (bufSize > sizeof(Fs_Stats)) {
  312.             bufSize = sizeof(Fs_Stats);
  313.         }
  314.         bcopy((Address) &fs_Stats, buffer, bufSize);
  315.         status = SUCCESS;
  316.         } else {
  317.         status = FS_INVALID_ARG;
  318.         }
  319.         break;
  320.     }
  321.     case FS_RETURN_LIFE_TIMES: {
  322.         if (bufSize >= sizeof(Fs_TypeStats)) {
  323.         bcopy((Address)&fs_TypeStats, buffer, sizeof(Fs_TypeStats));
  324.         status = SUCCESS;
  325.         } else {
  326.         status = FS_INVALID_ARG;
  327.         }
  328.         break;
  329.     }
  330.     case FS_GET_FRAG_INFO: {
  331.         int    *arrPtr = (int *)buffer;
  332.  
  333.         Fscache_CheckFragmentation(arrPtr, arrPtr + 1, arrPtr + 2);
  334.         break;
  335.     }
  336.     case FS_SET_CLEANER_PROCS:
  337.         SWAP_TO_BUFFER(fscache_MaxBlockCleaners, buffer);
  338.         break;
  339.     case FS_SET_READ_AHEAD:
  340.         SWAP_TO_BUFFER(fscache_NumReadAheadBlocks, buffer);
  341.         break;
  342.     case FS_SET_RA_TRACING:
  343.         SWAP_TO_BUFFER(fscache_RATracing, buffer);
  344.         break;
  345.     case FS_REREAD_SUMMARY_INFO:
  346.         status = Fsdm_RereadSummaryInfo(buffer);
  347.         break;
  348.     case FS_SET_BLOCK_SKEW: {
  349.         /*
  350.          * Set the block allocation gap.
  351.          */
  352.         extern int ofs_AllocGap;
  353.         SWAP_TO_BUFFER(ofs_AllocGap, buffer);
  354.         break;
  355.     }
  356.     case FS_DO_L1_COMMAND:
  357.         Dev_InvokeConsoleCmd(*(int *)buffer);
  358.         break;
  359.     default:
  360.         if ((command >= FS_FIRST_LFS_COMMAND) &&
  361.             (command <= FS_LAST_LFS_COMMAND)) {
  362.         status = Lfs_Command(command, bufSize, buffer);
  363.         } else {
  364.         status = FS_INVALID_ARG;
  365.         }
  366.     }
  367.     return(status);
  368. }
  369.  
  370. #ifdef notdef
  371. /*
  372.  *----------------------------------------------------------------------
  373.  *
  374.  * Fs_Cat --
  375.  *
  376.  *    Cat a file to the screen.  The named file is opened, then
  377.  *    a series of reads are done and the returned data is printed
  378.  *    on the screen.  (Used when testing simple kernels.)
  379.  *
  380.  * Results:
  381.  *    0 or an error code from any of the file operations.
  382.  *
  383.  * Side effects:
  384.  *    Does an open, reads and write, and a close.
  385.  *
  386.  *----------------------------------------------------------------------
  387.  */
  388. int
  389. Fs_Cat(fileName)
  390.     char *fileName;
  391. {
  392.     int error;
  393.     Fs_Stream *streamPtr;
  394.     int offset;
  395.     Address buffer;
  396.  
  397.     streamPtr = (Fs_Stream *)NIL;
  398.     error = Fs_Open(fileName, FS_READ|FS_FOLLOW, FS_FILE, 0, &streamPtr);
  399.     if (error) {
  400.     return(error);
  401.     }
  402.  
  403. #define CAT_BUFSIZE    80
  404.  
  405.     buffer = malloc(CAT_BUFSIZE);
  406.     offset = 0;
  407.     while (1) {
  408.     int savedLen, len;
  409.  
  410.     bzero(buffer, CAT_BUFSIZE);
  411.  
  412.     savedLen = len = CAT_BUFSIZE;
  413.     error = Fs_Read(streamPtr, buffer, offset, &len);
  414.     if (error || len < savedLen) {
  415.         break;
  416.     } else {
  417.         offset += len;
  418.     }
  419.     printf("%s", buffer);
  420.     }
  421.     (void)Fs_Close(streamPtr);
  422.     free(buffer);
  423.     return(error);
  424. }
  425. #endif /* notdef */
  426.  
  427. #ifdef notdef
  428. /*
  429.  *----------------------------------------------------------------------
  430.  *
  431.  * Fs_Copy --
  432.  *
  433.  *    Copy a file. (Used when testing simple kernels.)
  434.  *
  435.  * Results:
  436.  *    0 or an error code from any of the file operations.
  437.  *
  438.  * Side effects:
  439.  *    Creates a copy of the first file in the second.
  440.  *
  441.  *----------------------------------------------------------------------
  442.  */
  443. int
  444. Fs_Copy(srcFileName, dstFileName)
  445.     char *srcFileName;
  446.     char *dstFileName;
  447. {
  448.     int error;
  449.     Fs_Stream *srcStreamPtr;
  450.     Fs_Stream *dstStreamPtr;
  451.     int offset;
  452.     Address buffer;
  453.  
  454.     srcStreamPtr = (Fs_Stream *)NIL;
  455.     error = Fs_Open(srcFileName, FS_READ|FS_FOLLOW, FS_FILE, 0, &srcStreamPtr);
  456.     if (error) {
  457.     Sys_SafePrintf("Fs_Copy: can't open source file (%s)\n", srcFileName);
  458.     return(error);
  459.     }
  460.     dstStreamPtr = (Fs_Stream *)NIL;
  461.     error = Fs_Open(dstFileName, FS_CREATE|FS_WRITE|FS_FOLLOW, FS_FILE, 0666, &dstStreamPtr);
  462.     if (error) {
  463.     Sys_SafePrintf("Fs_Copy: can't open destination file (%s)\n",
  464.                  dstFileName);
  465.     (void)Fs_Close(srcStreamPtr);
  466.     return(error);
  467.     }
  468.  
  469. #define CP_BUFSIZE    2048
  470.  
  471.     buffer = malloc(CP_BUFSIZE);
  472.     offset = 0;
  473.     while (1) {
  474.     int len;
  475.  
  476.     len = CP_BUFSIZE;
  477.     error = Fs_Read(srcStreamPtr, buffer, offset, &len);
  478.     if (error) {
  479.         Sys_SafePrintf("Fs_Copy: read failed\n");
  480.         break;
  481.     } else if (len == 0) {
  482.         break ;
  483.     }
  484.     error = Fs_Write(dstStreamPtr, buffer, offset, &len);
  485.     if (error) {
  486.         Sys_SafePrintf("Fs_Copy: write failed\n");
  487.         break;
  488.     }
  489.     offset += len;
  490.     }
  491.     Sys_SafePrintf("Fs_Copy: copied %d bytes\n", offset);
  492.  
  493.     (void)Fs_Close(srcStreamPtr);
  494.     (void)Fs_Close(dstStreamPtr);
  495.     free(buffer);
  496.     return(error);
  497. }
  498. #endif /* notdef */
  499.